use bios_basic::rbum::dto::rbum_filer_dto::{RbumBasicFilterReq, RbumItemRelFilterReq};
use bios_basic::rbum::rbum_enumeration::RbumRelFromKind;
use bios_basic::rbum::serv::rbum_item_serv::RbumItemCrudOperation;
use bios_basic::spi::dto::spi_bs_dto::{SpiBsAddReq, SpiBsDetailResp, SpiBsFilterReq, SpiBsModifyReq, SpiBsSummaryResp};
use bios_basic::spi::serv::spi_bs_serv::SpiBsServ;
use bios_basic::spi::spi_constants;

use tardis::web::context_extractor::TardisContextExtractor;

use tardis::web::poem_openapi;
use tardis::web::poem_openapi::param::{Path, Query};
use tardis::web::poem_openapi::payload::Json;
use tardis::web::web_resp::{TardisApiResult, TardisPage, TardisResp, Void};

use crate::dto::plugin_bs_dto::{PluginBsAddReq, PluginBsCertInfoResp, PluginBsInfoResp};
use crate::serv::plugin_bs_serv::PluginBsServ;
#[derive(Clone)]

pub struct PluginCiBsApi;

/// Interface Console Backend rel Service API
///
/// 插件 CI 后台服务 API
#[poem_openapi::OpenApi(prefix_path = "/ci/manage/bs", tag = "bios_basic::ApiTag::Interface")]
impl PluginCiBsApi {
    /// Add Backend Service
    ///
    /// 添加后端服务
    #[oai(path = "/", method = "post")]
    async fn add(&self, mut add_req: Json<SpiBsAddReq>, ctx: TardisContextExtractor) -> TardisApiResult<String> {
        let mut funs = crate::get_tardis_inst();
        funs.begin().await?;
        let result = SpiBsServ::add_item(&mut add_req.0, &funs, &ctx.0).await?;
        funs.commit().await?;
        TardisResp::ok(result)
    }

    /// Modify Backend Service
    ///
    /// 修改后端服务
    #[oai(path = "/:id", method = "patch")]
    async fn modify(&self, id: Path<String>, mut modify_req: Json<SpiBsModifyReq>, ctx: TardisContextExtractor) -> TardisApiResult<Void> {
        let mut funs = crate::get_tardis_inst();
        funs.begin().await?;
        SpiBsServ::modify_item(&id.0, &mut modify_req.0, &funs, &ctx.0).await?;
        funs.commit().await?;
        TardisResp::ok(Void {})
    }

    /// Get Backend Service
    ///
    /// 获取后端服务
    #[oai(path = "/:id", method = "get")]
    async fn get(&self, id: Path<String>, ctx: TardisContextExtractor) -> TardisApiResult<SpiBsDetailResp> {
        let funs = crate::get_tardis_inst();
        let result = SpiBsServ::get_bs(&id.0, &funs, &ctx.0).await?;
        TardisResp::ok(result)
    }

    /// Find Backend Services
    ///
    /// 查找后端服务列表
    #[oai(path = "/", method = "get")]
    async fn paginate(
        &self,
        id: Query<Option<String>>,
        name: Query<Option<String>>,
        kind_id: Query<Option<String>>,
        kind_code: Query<Option<String>>,
        kind_codes: Query<Option<String>>,
        app_tenant_id: Query<Option<String>>,
        page_number: Query<u32>,
        page_size: Query<u32>,
        desc_by_create: Query<Option<bool>>,
        desc_by_update: Query<Option<bool>>,
        ctx: TardisContextExtractor,
    ) -> TardisApiResult<TardisPage<SpiBsSummaryResp>> {
        let funs = crate::get_tardis_inst();
        let rel = app_tenant_id.0.map(|app_tenant_id| RbumItemRelFilterReq {
            rel_by_from: true,
            tag: Some(spi_constants::SPI_IDENT_REL_TAG.to_string()),
            from_rbum_kind: Some(RbumRelFromKind::Item),
            rel_item_id: Some(app_tenant_id),
            ..Default::default()
        });
        let kind_codes: Option<Vec<String>> = kind_codes.0.map(|kind_codes| kind_codes.split(',').map(|kind_code| kind_code.to_string()).collect());
        let result = SpiBsServ::paginate_items(
            &SpiBsFilterReq {
                basic: RbumBasicFilterReq {
                    ids: id.0.map(|id| vec![id]),
                    name: name.0,
                    ..Default::default()
                },
                kind_id: kind_id.0,
                kind_code: kind_code.0,
                kind_codes: kind_codes.clone(),
                domain_code: Some(funs.module_code().to_string()),
                rel,
                ..Default::default()
            },
            page_number.0,
            page_size.0,
            desc_by_create.0,
            desc_by_update.0,
            &funs,
            &ctx.0,
        )
        .await?;
        TardisResp::ok(result)
    }

    /// Delete Backend Service
    ///
    /// 删除后端服务
    #[oai(path = "/:id", method = "delete")]
    async fn delete(&self, id: Path<String>, ctx: TardisContextExtractor) -> TardisApiResult<Void> {
        let mut funs = crate::get_tardis_inst();
        funs.begin().await?;
        SpiBsServ::delete_item_with_all_rels(&id.0, &funs, &ctx.0).await?;
        funs.commit().await?;
        TardisResp::ok(Void {})
    }

    /// Add Plugin Service Rel App/Tenant
    ///
    /// 添加插件服务关系
    #[oai(path = "/rel", method = "put")]
    async fn add_plugin_rel_agg(&self, mut add_req: Json<PluginBsAddReq>, ctx: TardisContextExtractor) -> TardisApiResult<String> {
        let mut funs = crate::get_tardis_inst();
        funs.begin().await?;
        let result = PluginBsServ::add_or_modify_plugin_rel_agg(&mut add_req.0, &funs, &ctx.0).await?;
        funs.commit().await?;
        ctx.0.execute_task().await?;
        TardisResp::ok(result)
    }

    /// Get Plugin Service Rel App/Tenant Support empty
    ///
    /// 获取插件服务关系（支持空）
    #[oai(path = "/rel/:rel_id/empty", method = "get")]
    async fn get_empty_bs_rel_agg(&self, rel_id: Path<String>, ctx: TardisContextExtractor) -> TardisApiResult<PluginBsInfoResp> {
        let funs = crate::get_tardis_inst();
        let result = PluginBsServ::get_bs(&rel_id.0, false, &funs, &ctx.0).await?;
        TardisResp::ok(result)
    }

    /// Get Plugin Service Rel App/Tenant Hide Secret
    ///
    /// 获取插件服务关系（隐藏密钥）
    #[oai(path = "/rel/hide/secret/:rel_id", method = "get")]
    async fn get_bs_rel_hide_secret_agg(&self, rel_id: Path<String>, ctx: TardisContextExtractor) -> TardisApiResult<PluginBsInfoResp> {
        let funs = crate::get_tardis_inst();
        let result = PluginBsServ::get_bs(&rel_id.0, true, &funs, &ctx.0).await?;
        TardisResp::ok(result)
    }

    /// Get Plugin Service Rel App/Tenant
    ///
    /// 获取插件服务关系
    #[oai(path = "/rel/:rel_id", method = "get")]
    async fn get_bs_rel_agg(&self, rel_id: Path<String>, ctx: TardisContextExtractor) -> TardisApiResult<PluginBsInfoResp> {
        let funs = crate::get_tardis_inst();
        let result = PluginBsServ::get_bs(&rel_id.0, false, &funs, &ctx.0).await?;
        TardisResp::ok(result)
    }

    /// Get Plugin Service Rel App/Tenant
    ///
    /// 获取插件服务关系
    #[oai(path = "/rel/up/:kind_code", method = "get")]
    async fn get_bs_by_kind_code(&self, kind_code: Path<String>, ctx: TardisContextExtractor) -> TardisApiResult<PluginBsCertInfoResp> {
        let funs = crate::get_tardis_inst();
        let result = PluginBsServ::get_bs_by_up_kind_code(&kind_code.0, None, false, &funs, &ctx.0).await?;
        TardisResp::ok(result)
    }

    /// Find Plugin Services rel App/Tenant
    ///
    /// 获取插件服务关系
    #[oai(path = "/rel", method = "get")]
    async fn paginate_bs_rel_agg(
        &self,
        kind_id: Query<Option<String>>,
        bs_id: Query<Option<String>>,
        app_tenant_id: Query<String>,
        page_number: Query<u32>,
        page_size: Query<u32>,
        desc_by_create: Query<Option<bool>>,
        desc_by_update: Query<Option<bool>>,
        ctx: TardisContextExtractor,
    ) -> TardisApiResult<TardisPage<PluginBsInfoResp>> {
        let funs = crate::get_tardis_inst();
        let result = PluginBsServ::paginate_bs_rel_agg(
            kind_id.0,
            bs_id.0,
            &app_tenant_id.0,
            false,
            page_number.0,
            page_size.0,
            desc_by_create.0,
            desc_by_update.0,
            &funs,
            &ctx.0,
        )
        .await?;
        TardisResp::ok(result)
    }

    #[oai(path = "/rel/hide/secret", method = "get")]
    async fn paginate_bs_rel_hide_secret_agg(
        &self,
        kind_id: Query<Option<String>>,
        bs_id: Query<Option<String>>,
        app_tenant_id: Query<String>,
        page_number: Query<u32>,
        page_size: Query<u32>,
        desc_by_create: Query<Option<bool>>,
        desc_by_update: Query<Option<bool>>,
        ctx: TardisContextExtractor,
    ) -> TardisApiResult<TardisPage<PluginBsInfoResp>> {
        let funs = crate::get_tardis_inst();
        let result = PluginBsServ::paginate_bs_rel_agg(
            kind_id.0,
            bs_id.0,
            &app_tenant_id.0,
            true,
            page_number.0,
            page_size.0,
            desc_by_create.0,
            desc_by_update.0,
            &funs,
            &ctx.0,
        )
        .await?;
        TardisResp::ok(result)
    }

    /// Delete Plugin Service Rel App/Tenant
    ///
    /// 删除插件服务关系
    #[oai(path = "/rel/:rel_id", method = "delete")]
    async fn delete_rel(&self, rel_id: Path<String>, ctx: TardisContextExtractor) -> TardisApiResult<Void> {
        let mut funs = crate::get_tardis_inst();
        funs.begin().await?;
        PluginBsServ::delete_plugin_rel(&rel_id.0, &funs, &ctx.0).await?;
        funs.commit().await?;
        ctx.0.execute_task().await?;
        TardisResp::ok(Void {})
    }

    /// find Plugin Service Rel App/Tenant sub bind ids
    ///
    /// 获取插件服务关系下级绑定ID
    #[oai(path = "/find/:id/rel/:app_tenant_id/sub/bind", method = "get")]
    async fn find_sub_bind_ids(&self, id: Path<String>, app_tenant_id: Path<String>, ctx: TardisContextExtractor) -> TardisApiResult<Vec<String>> {
        let funs = crate::get_tardis_inst();
        let sub_bind_ids = PluginBsServ::find_sub_bind_ids(&id.0, &app_tenant_id.0, &funs, &ctx.0).await?;
        TardisResp::ok(sub_bind_ids)
    }
}
